package com.jrapider.manager.service.menu;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jrapider.CommonConstants;
import com.jrapider.compent.dict.DictData;
import com.jrapider.compent.dict.IDictProvider;
import com.jrapider.exception.TransRollbackException;
import com.jrapider.manager.data.om.SysMenu;
import com.jrapider.om.JSONResult;
import com.jrapider.om.PageInfo;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import lombok.extern.log4j.Log4j2;

import com.jrapider.manager.data.mapper.SysMenuMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service
@Log4j2
public class SysMenuService extends ServiceImpl<SysMenuMapper, SysMenu> implements IDictProvider {

    public IPage<SysMenu> queryMenuWithRole(String link, IPage<SysMenu> page, String title, Long roleId) {
        List<SysMenu> list;
        if (CommonConstants.DICT_TF_TRUE.equals(link)) {
            list = baseMapper.queryMenuWithRole(page, "%" + title + "%", roleId);
            page.setRecords(list);
        } else if (CommonConstants.DICT_TF_FALSE.equals(link)) {
            list = baseMapper.queryMenuWithNoRole(page, "%" + title + "%", roleId);
            page.setRecords(list);
        } else {
            SysMenu condition = new SysMenu();
            QueryWrapper<SysMenu> qw = new QueryWrapper(condition);
            qw.like("title", title);
            page = baseMapper.selectPage(page, qw);
            list = page.getRecords();
        }
        for(SysMenu sysMenu:list){
            Long count = baseMapper.existRole(sysMenu.getId(),roleId);
            if(count > 0){
                sysMenu.setLink(CommonConstants.DICT_TRUE);
            }else{
                sysMenu.setLink(CommonConstants.DICT_FALSE);
            }
        }

        return page;
    }
    @Transactional(rollbackFor = TransRollbackException.class)
    public JSONObject linkMenu(Long roleId, Long[] menuIds, Boolean link) {

        if (link) {
            try {
                baseMapper.insertMenuRelation(roleId, menuIds);
            }catch (DuplicateKeyException e){
                throw new TransRollbackException("部分用户已关联,无法继续关联");
            }

        } else {
            for (Long userId : menuIds) {
                baseMapper.deleteMenuRelation(roleId, userId);
            }
        }
        return JSONResult.newBuilder().success("更新成功").build();
    }

    @Override
    public Set<String> supportCodes() {
        return new HashSet<String>(){{
            add("menu");
        }};
    }

    @Override
    public List<DictData> getDict(String code) {
        List<SysMenu> list = baseMapper.selectList(new QueryWrapper<SysMenu>().isNull("pid"));
        return list.stream().map(sysMenu -> new DictData(){{
            setValue(sysMenu.getId()+"");
            setCode(code);
            setNote(sysMenu.getTitle());
        }}).collect(Collectors.toList());
    }

    @Override
    public List<DictData> getDict(String s, String s1, PageInfo pageInfo) {
        return getDict(s);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdate(SysMenu entity) {
        super.saveOrUpdate(entity);
        sortMenu(null,"");
        return true;
    }

    private void sortMenu(Long pid,String preferIndex) {
        List<SysMenu> menus = baseMapper.selectChild(pid);
        int i =0;
        for(SysMenu sysMenu:menus){
            sysMenu.setSortcode(preferIndex+String.format("%02d",i++));
            baseMapper.updateById(sysMenu);
            sortMenu(sysMenu.getId(),sysMenu.getSortcode());
        }
    }
}
